/* *
 *
 *  (c) 2010-2019 Torstein Honsi
 *
 *  License: www.highcharts.com/license
 *
 *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
 *
 * */
"use strict";
import H from "./Globals.js";
/* globals MSPointerEvent, PointerEvent */
import U from "./Utilities.js";
var extend = U.extend,
  objectEach = U.objectEach,
  wrap = U.wrap;
import "./Pointer.js";
var addEvent = H.addEvent,
  charts = H.charts,
  css = H.css,
  doc = H.doc,
  hasTouch = H.hasTouch,
  noop = H.noop,
  Pointer = H.Pointer,
  removeEvent = H.removeEvent,
  win = H.win;
if (!hasTouch && (win.PointerEvent || win.MSPointerEvent)) {
  // The touches object keeps track of the points being touched at all times
  var touches = {},
    hasPointerEvent = !!win.PointerEvent,
    getWebkitTouches = function () {
      var fake = [];
      fake.item = function (i) {
        return this[i];
      };
      objectEach(touches, function (touch) {
        fake.push({
          pageX: touch.pageX,
          pageY: touch.pageY,
          target: touch.target,
        });
      });
      return fake;
    },
    translateMSPointer = function (e, method, wktype, func) {
      var p;
      if (
        (e.pointerType === "touch" ||
          e.pointerType === e.MSPOINTER_TYPE_TOUCH) &&
        charts[H.hoverChartIndex]
      ) {
        func(e);
        p = charts[H.hoverChartIndex].pointer;
        p[method]({
          type: wktype,
          target: e.currentTarget,
          preventDefault: noop,
          touches: getWebkitTouches(),
        });
      }
    };
  /* eslint-disable no-invalid-this, valid-jsdoc */
  // Extend the Pointer prototype with methods for each event handler and more
  extend(
    Pointer.prototype,
    /** @lends Pointer.prototype */ {
      /**
       * @private
       * @function Highcharts.Pointer#onContainerPointerDown
       *
       * @param {Highcharts.PointerEventObject} e
       *
       * @return {void}
       */
      onContainerPointerDown: function (e) {
        translateMSPointer(
          e,
          "onContainerTouchStart",
          "touchstart",
          function (e) {
            touches[e.pointerId] = {
              pageX: e.pageX,
              pageY: e.pageY,
              target: e.currentTarget,
            };
          }
        );
      },
      /**
       * @private
       * @function Highcharts.Pointer#onContainerPointerMove
       *
       * @param {Highcharts.PointerEventObject} e
       *
       * @return {void}
       */
      onContainerPointerMove: function (e) {
        translateMSPointer(
          e,
          "onContainerTouchMove",
          "touchmove",
          function (e) {
            touches[e.pointerId] = { pageX: e.pageX, pageY: e.pageY };
            if (!touches[e.pointerId].target) {
              touches[e.pointerId].target = e.currentTarget;
            }
          }
        );
      },
      /**
       * @private
       * @function Highcharts.Pointer#onDocumentPointerUp
       *
       * @param {Highcharts.PointerEventObject} e
       *
       * @return {void}
       */
      onDocumentPointerUp: function (e) {
        translateMSPointer(e, "onDocumentTouchEnd", "touchend", function (e) {
          delete touches[e.pointerId];
        });
      },
      /**
       * Add or remove the MS Pointer specific events
       *
       * @private
       * @function Highcharts.Pointer#batchMSEvents
       *
       * @param {Function} fn
       *
       * @return {void}
       */
      batchMSEvents: function (fn) {
        fn(
          this.chart.container,
          hasPointerEvent ? "pointerdown" : "MSPointerDown",
          this.onContainerPointerDown
        );
        fn(
          this.chart.container,
          hasPointerEvent ? "pointermove" : "MSPointerMove",
          this.onContainerPointerMove
        );
        fn(
          doc,
          hasPointerEvent ? "pointerup" : "MSPointerUp",
          this.onDocumentPointerUp
        );
      },
    }
  );
  // Disable default IE actions for pinch and such on chart element
  wrap(Pointer.prototype, "init", function (proceed, chart, options) {
    proceed.call(this, chart, options);
    if (this.hasZoom) {
      // #4014
      css(chart.container, {
        "-ms-touch-action": "none",
        "touch-action": "none",
      });
    }
  });
  // Add IE specific touch events to chart
  wrap(Pointer.prototype, "setDOMEvents", function (proceed) {
    proceed.apply(this);
    if (this.hasZoom || this.followTouchMove) {
      this.batchMSEvents(addEvent);
    }
  });
  // Destroy MS events also
  wrap(Pointer.prototype, "destroy", function (proceed) {
    this.batchMSEvents(removeEvent);
    proceed.call(this);
  });
}
